﻿using System;
using System.Collections.Generic;
using IInject.Extensibility;
using IInject.Registration;
using IInject.Resolution;

namespace IInject.Internal
{
	/// <summary>
	/// 
	/// </summary>
	public interface IExtensible : IEnumerable<IExtension>
	{
		/// <summary>
		/// The event that is raised when a context is registering.
		/// </summary>
		event Action<RegistryContext> ItemRegistering;

		/// <summary>
		/// The event that is raised when a context is registered.
		/// </summary>
		event Action<RegistryContext> ItemRegistered;

		/// <summary>
		/// The event that is raised when a context is resolving.
		/// </summary>
		event Action<TypeDependency> ItemResolving;

		/// <summary>
		/// Adds the extension.
		/// </summary>
		/// <param name="extension">The extension.</param>
		void AddExtension(IExtension extension);

		/// <summary>
		/// Adds the extension.
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="extension">The extension.</param>
		void AddExtension<T>(T extension) where T : IExtension;

		/// <summary>
		/// Removes the extension.
		/// </summary>
		/// <param name="extension">The extension.</param>
		/// <returns></returns>
		bool RemoveExtension(IExtension extension);

		/// <summary>
		/// Removes the extension.
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="extension">The extension.</param>
		/// <returns></returns>
		bool RemoveExtension<T>(T extension) where T : IExtension;

		/// <summary>
		/// Called when [context registered].
		/// </summary>
		/// <param name="context">The context.</param>
		void OnContextRegistered(RegistryContext context);

		/// <summary>
		/// Called when [context registering].
		/// </summary>
		/// <param name="context">The context.</param>
		void OnContextRegistering(RegistryContext context);

		/// <summary>
		/// Called when [context resolving].
		/// </summary>
		/// <param name="dependency">The dependency.</param>
		void OnContextResolving(TypeDependency dependency);
	}
}